package com.sr.service.impl;


import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.core.RedisOperations;
import org.springframework.data.redis.core.SessionCallback;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import com.sr.service.RedisTemplateService;

@Service
public class RedisTemplateServiceImpl implements RedisTemplateService {

    @Autowired
    private StringRedisTemplate redisTemplate = null;

    /**
     * 使用SessionCallback接口实现多个命令在一个Redis连接中执行
     */
    @Override
    public void execMultiCommand() {
        // 使用Java 8 lambda表达式
        SessionCallback session = ops -> {
            ops.boundValueOps("key1").set("abc");
            ops.boundHashOps("hash").put("hash-key-1", "hash-value-1");
            return ops.boundValueOps("key1").get();
        };

        String value = (String) redisTemplate.execute(session);
        System.out.println(value);
    }

    /**
     * 使用SessionCallback接口实现事务在一个Redis连接中执行
     */
    @Override
    public void execTransaction() {
        // 使用Java 8 lambda表达式
        SessionCallback session = ops -> {
            // 监控
            ops.watch("key1");
            // 开启事务
            ops.multi();
            // 注意，命令都不会被马上执行，只会放到Redis的队列中，只会返回为null
            ops.boundValueOps("key1").set("abc");
            ops.boundHashOps("hash").put("hash-key-1", "hash-value-1");
            ops.opsForValue().get("key1");
            // 执行exec方法后会触发事务执行，返回结果，存放到list中
            List result = ops.exec();
            return result;
        };
        List list = (List) redisTemplate.execute(session);
        System.out.println(list);
    }

    /**
     * 执行流水线，将多个命令一次性发送给Redis服务器
     */
    @Override
    public void execPipeline() {
        // 使用匿名类实现
        SessionCallback session = new SessionCallback() {
            @Override
            public Object execute(RedisOperations ops)
                    throws DataAccessException {
                // 在流水线下，命令不会马上返回结果，结果是一次性执行后返回的
                ops.opsForValue().set("key1", "value1");
                ops.opsForHash().put("hash", "key-hash-1", "value-hash-1");
                ops.opsForValue().get("key1");
                return null;
            };
        };
        List list = redisTemplate.executePipelined(session);
        System.out.println(list);
    }

}
